package com.tanhua.admin.service;

import com.tanhua.admin.mapper.AnalysisMapper;
import com.tanhua.admin.mapper.LogMapper;
import com.tanhua.model.chart.AnnualData;
import com.tanhua.model.chart.ChartDateVo;
import com.tanhua.model.domain.Analysis;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Service
public class AnalysisService {

    @Autowired
    private LogMapper logMapper;

    @Autowired
    private AnalysisMapper analysisMapper;

    /**
     * 定时统计tb_log表中的数据，保存或者更新tb_analysis表
     *  1、查询tb_log表（注册用户数，登录用户数，活跃用户数，次日留存）
     *  2、构造Analysis对象
     *  3、保存或者更新
     */
    /*public void analysis() throws ParseException {
        *//*1、定义查询的日期
        String todayStr = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        String yesdayStr = DateUtil.yesterday().toString("yyyy-MM-dd");*//*
        *//**
         * 基于数据表最新时间，使用自定义时间
         *//*
        String todayStr = "2020-09-25";
        String yesdayStr = "2020-09-25";
        //2、统计数据-注册数量
        Integer regCount = logMapper.queryByTypeAndLogTime("0102", todayStr);
        //3、统计数据-登录数量
        Integer loginCount = logMapper.queryByTypeAndLogTime("0101", todayStr);
        //4、统计数据-活跃数量
        Integer activeCount = logMapper.queryByLogTime(todayStr);
        //5、统计数据-次日留存
        Integer numRetention1d = logMapper.queryNumRetention1d(todayStr, yesdayStr);
        //6、构造Analysis对象
        //7、根据日期查询数据
        *//*LambdaQueryWrapper<Analysis> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Analysis::getRecordDate,"2020-09-25");*//*
        Analysis analysis = analysisMapper.queryAnalysisByDay("2020-09-25");
        //8、如果存在，更新，如果不存在保存
        if(analysis != null) {
            analysis.setNumRegistered(regCount);
            analysis.setNumLogin(loginCount);
            analysis.setNumActive(activeCount);
            analysis.setNumRetention1d(numRetention1d);
            analysisMapper.updateById(analysis);
        }else {
            analysis = new Analysis();
            analysis.setNumRegistered(regCount);
            analysis.setNumLogin(loginCount);
            analysis.setNumActive(activeCount);
            analysis.setNumRetention1d(numRetention1d);
            analysis.setRecordDate(new SimpleDateFormat("yyyy-MM-dd").parse(todayStr));
            analysis.setCreated(new Date());
            analysisMapper.insert(analysis);
        }
    }*/

    /**
     * 查询总用户数
     * @return
     */
    public Integer queryCumulativeUsers() {
        return analysisMapper.queryCumulativeUsers();
    }

    /**
     * 查询今日信息
     * @param now
     * @return
     */
    public Analysis querySummary(Date now) {
        //根据当前时间实时查询今日信息
        /*LambdaQueryWrapper<Analysis> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Analysis::getRecordDate,"2020-09-25");*/
        Analysis analysis = analysisMapper.queryAnalysisByDay("2020-09-25");

        /**
         * 30天活跃用户数
         */
        //调用mapper层查询
        int day30 = 30;
        Integer numActive_30 = analysisMapper.queryActiveSum_day("2020-09-25",day30);
        //将查询结果存入Analysis中
        analysis.setGetNumActive30(numActive_30);

        /**
         * 7天活跃用户数
         */
        int day7 = 7;
        Integer numActive_7 = analysisMapper.queryActiveSum_day("2020-09-25",day7);
        analysis.setGetNumActive7(numActive_7);

        /**
         * 查询今日活跃用户数
         */
        Integer numActive_today = analysisMapper.queryActiveSum_today("2020-09-25");
        analysis.setNumActive(numActive_today);

        /**
         * 今日登录用户
         */
        Integer numLogin_today = analysisMapper.queryNumLogin_today("2020-09-25");
        analysis.setNumLogin(numLogin_today);

        //返回结果
        return analysis;
    }

    /**
     * 查询
     * 注册用户数，活跃用户数，次日留存
     * @return
     */
    public ChartDateVo queryBasicStatistics(String[] time, String type){
        //提取时间sd ed
        String sd = time[0];
        String ed = time[1];
        String sd_lastYear = time[2];
        String ed_lastYear = time[3];
        //查询模式转换
        switch (type) {
            case "101"://注册用户数--新增用户数
                /*查询 sd - ed 范围内的新增用户，thisYear
                * 将sd、ed减少一年，再次查询，lastYear*/
                            //这个是公共类，可以产生thisYear、lastYear
                ChartDateVo chartDateVo_register = new ChartDateVo();
                //thisYear
                List<Analysis> userRegister_thisYear = analysisMapper.queryRegister_days(sd, ed);
                //调用方法getAnnualDataList，简化封装过程
                List<AnnualData> thisYear_register = getAnnualDataList(userRegister_thisYear, "101");
                //封装thisYear至Vo
                chartDateVo_register.setThisYear(thisYear_register);

                //lastYear
                List<Analysis> userRegister_lastYear = analysisMapper.queryRegister_days(sd_lastYear, ed_lastYear);
                //调用方法getAnnualDataList，简化封装过程
                List<AnnualData> lastYear_register = getAnnualDataList(userRegister_lastYear, "101");
                //封装lastYear至Vo
                chartDateVo_register.setLastYear(lastYear_register);
                //返回
                return chartDateVo_register;
            case "102"://活跃用户数
                /*查询 sd - ed 范围内的活跃用户数 Integet*/
                        //这个是公共类，可以产生thisYear、lastYear
                ChartDateVo chartDateVo_active = new ChartDateVo();
                //thisYear
                List<Analysis> userActive_thisYear = analysisMapper.queryActive_days(sd, ed);
                //调用方法getAnnualDataList，简化封装过程
                List<AnnualData> thisYear_active = getAnnualDataList(userActive_thisYear, "102");
                //封装thisYear至Vo
                chartDateVo_active.setThisYear(thisYear_active);

                //lastYear
                List<Analysis> userActive_lastYear = analysisMapper.queryActive_days(sd_lastYear, ed_lastYear);
                //调用方法getAnnualDataList，简化封装过程
                List<AnnualData> lastYear_active = getAnnualDataList(userActive_lastYear, "102");
                //封装thisYear至Vo
                chartDateVo_active.setLastYear(lastYear_active);
                //返回
                return chartDateVo_active;
            case "103"://次日留存率
                    //这个是公共类，可以产生thisYear、lastYear
                ChartDateVo chartDateVo_retention1d = new ChartDateVo();
                //thisYear
                List<Analysis> retention1d_thisYear = analysisMapper.queryRetention1d(sd,ed);
                List<AnnualData> thisYear_retention1d = getAnnualDataList(retention1d_thisYear, "103");
                chartDateVo_retention1d.setThisYear(thisYear_retention1d);

                //lastYear
                List<Analysis> retention1d_lastYear = analysisMapper.queryRetention1d(sd_lastYear, ed_lastYear);
                //调用方法getAnnualDataList，简化封装过程
                List<AnnualData> lastYear_retention1d = getAnnualDataList(retention1d_lastYear, "103");
                //封装thisYear至Vo
                chartDateVo_retention1d.setLastYear(lastYear_retention1d);
                return chartDateVo_retention1d;
            default:
                break;
        }
        return null;
    }
    /**
     * 工具方法
     * 获取record_date的月份
     */
    public String getMonth(Date recordDate){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(recordDate);
        String month = String.valueOf(calendar.get(Calendar.MONTH) + 1);
        return month;
    }

    /**
     * 工具方法
     * 获取record_date的天数
     */
    public String getDay(Date recordDate){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(recordDate);
        String day = String.valueOf(calendar.get(Calendar.DAY_OF_MONTH));
        return day;
    }

    /**
     * 工具方法：整合代码type 101，type 102
     */
    /*传入参数：查询结果、查询模式*/
    public List<AnnualData> getAnnualDataList(List<Analysis> analysisList,String type){
    //创建ChartDateVo类下AnnualData集合，存放AnnualData
        List<AnnualData> annualDataList = new ArrayList<>();
    //增强遍历查询结果annualDataList
            //rate阶段仅用：昨日留存rate计算--创建一个变量储存昨日用户登录数据
                //昨日注册用户
        Integer registered = 0;
                //中间变量--存放rate率值--double保留三位小数
        Double rate = 0.000;
                //计数器i
        int i = 0;
        for (Analysis analysis : analysisList) {
            //创建AnnualData，存放title、amount
            AnnualData annualData = new AnnualData();
                //封装数量：3种模式，1.register 2.active 3.numRetention1d
            Integer amount = 0;
            switch (type) {
                case "101":
                    amount = analysis.getNumRegistered();
                    break;
                case "102":
                    amount= analysis.getNumActive();
                    break;
                case "103":
                    //查询数据表留存数据的时候会查询前端录入日期的前一天，保留该天registered数据，并跳过这次增强for循环
                    if (i == 0){
                        //将昨日registered用户的数量储存
                        registered = analysis.getNumRegistered();
                        i++;
                        continue;
                    }
                    //计算留存率
                        //获取本次的numRetention1d留存人数
                    Integer numRetention1d = analysis.getNumRetention1d();
                        //如昨日registered用户不为0，计算有意义，否则无意义，为0
                    if (registered != 0) {
                        BigDecimal r = new BigDecimal((double)numRetention1d/registered);
                        rate = r.setScale(3,BigDecimal.ROUND_HALF_UP).doubleValue();
                    } else {
                        rate = 0.000;
                    }
                    //重置registered为本次数据，供下次计算
                    registered = analysis.getNumRegistered();
                    //处理amount
                    amount = (int)(rate*1000);
                default:
                    break;
            }
                //封装数量-->amount
            annualData.setAmount(amount);
                //封装日期-->title
            String day = getDay(analysis.getRecordDate());
            annualData.setTitle(day);
                //封装好的AnnualData --> List<AnnualData>
            annualDataList.add(annualData);
        }
        return annualDataList;
    }
}
